/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 3.0 */

using System;

namespace Lucene.Net.Demo.Html
{
	
	/// <summary> An implementation of interface CharStream, where the stream is assumed to
	/// contain only ASCII characters (without unicode processing).
	/// </summary>
	
	public class SimpleCharStream
	{
		public const bool staticFlag = false;
		internal int bufsize;
		internal int available;
		internal int tokenBegin;
		public int bufpos = - 1;
		protected internal int[] bufline;
		protected internal int[] bufcolumn;
		
		protected internal int column = 0;
		protected internal int line = 1;
		
		protected internal bool prevCharIsCR = false;
		protected internal bool prevCharIsLF = false;
		
		protected internal System.IO.StreamReader inputStream;
		
		protected internal char[] buffer;
		protected internal int maxNextCharInd = 0;
		protected internal int inBuf = 0;
		
		protected internal virtual void  ExpandBuff(bool wrapAround)
		{
			char[] newbuffer = new char[bufsize + 2048];
			int[] newbufline = new int[bufsize + 2048];
			int[] newbufcolumn = new int[bufsize + 2048];
			
			try
			{
				if (wrapAround)
				{
					Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
					Array.Copy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
					buffer = newbuffer;
					
					Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
					Array.Copy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
					bufline = newbufline;
					
					Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
					Array.Copy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
					bufcolumn = newbufcolumn;
					
					maxNextCharInd = (bufpos += (bufsize - tokenBegin));
				}
				else
				{
					Array.Copy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
					buffer = newbuffer;
					
					Array.Copy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
					bufline = newbufline;
					
					Array.Copy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
					bufcolumn = newbufcolumn;
					
					maxNextCharInd = (bufpos -= tokenBegin);
				}
			}
			catch (System.Exception t)
			{
				throw new System.ApplicationException(t.Message);
			}
			
			
			bufsize += 2048;
			available = bufsize;
			tokenBegin = 0;
		}
		
		protected internal virtual void  FillBuff()
		{
			if (maxNextCharInd == available)
			{
				if (available == bufsize)
				{
					if (tokenBegin > 2048)
					{
						bufpos = maxNextCharInd = 0;
						available = tokenBegin;
					}
					else if (tokenBegin < 0)
						bufpos = maxNextCharInd = 0;
					else
						ExpandBuff(false);
				}
				else if (available > tokenBegin)
					available = bufsize;
				else if ((tokenBegin - available) < 2048)
					ExpandBuff(true);
				else
					available = tokenBegin;
			}
			
			int i;
			try
			{
				if ((i = inputStream.Read(buffer, maxNextCharInd, available - maxNextCharInd)) == - 1)
				{
					inputStream.Close();
					throw new System.IO.IOException();
				}
				else
					maxNextCharInd += i;
				return ;
			}
			catch (System.IO.IOException e)
			{
				--bufpos;
				Backup(0);
				if (tokenBegin == - 1)
					tokenBegin = bufpos;
				throw e;
			}
		}
		
		public virtual char BeginToken()
		{
			tokenBegin = - 1;
			char c = ReadChar();
			tokenBegin = bufpos;
			
			return c;
		}
		
		protected internal virtual void  UpdateLineColumn(char c)
		{
			column++;
			
			if (prevCharIsLF)
			{
				prevCharIsLF = false;
				line += (column = 1);
			}
			else if (prevCharIsCR)
			{
				prevCharIsCR = false;
				if (c == '\n')
				{
					prevCharIsLF = true;
				}
				else
					line += (column = 1);
			}
			
			switch (c)
			{
				
				case '\r': 
					prevCharIsCR = true;
					break;
				
				case '\n': 
					prevCharIsLF = true;
					break;
				
				case '\t': 
					column--;
					column += (8 - (column & 7));
					break;
				
				default: 
					break;
				
			}
			
			bufline[bufpos] = line;
			bufcolumn[bufpos] = column;
		}
		
		public virtual char ReadChar()
		{
			if (inBuf > 0)
			{
				--inBuf;
				
				if (++bufpos == bufsize)
					bufpos = 0;
				
				return buffer[bufpos];
			}
			
			if (++bufpos >= maxNextCharInd)
				FillBuff();
			
			char c = buffer[bufpos];
			
			UpdateLineColumn(c);
			return (c);
		}
		
		public virtual int GetEndColumn()
		{
			return bufcolumn[bufpos];
		}
		
		public virtual int GetEndLine()
		{
			return bufline[bufpos];
		}
		
		public virtual int GetBeginColumn()
		{
			return bufcolumn[tokenBegin];
		}
		
		public virtual int GetBeginLine()
		{
			return bufline[tokenBegin];
		}
		
		public virtual void  Backup(int amount)
		{
			
			inBuf += amount;
			if ((bufpos -= amount) < 0)
				bufpos += bufsize;
		}
		
		public SimpleCharStream(System.IO.StreamReader dstream, int startline, int startcolumn, int buffersize)
		{
			inputStream = dstream;
			line = startline;
			column = startcolumn - 1;
			
			available = bufsize = buffersize;
			buffer = new char[buffersize];
			bufline = new int[buffersize];
			bufcolumn = new int[buffersize];
		}
		
		public SimpleCharStream(System.IO.StreamReader dstream, int startline, int startcolumn) : this(dstream, startline, startcolumn, 4096)
		{
		}
		
		public SimpleCharStream(System.IO.StreamReader dstream):this(dstream, 1, 1, 4096)
		{
		}

        public virtual void  ReInit(System.IO.StreamReader dstream, int startline, int startcolumn, int buffersize)
		{
			inputStream = dstream;
			line = startline;
			column = startcolumn - 1;
			
			if (buffer == null || buffersize != buffer.Length)
			{
				available = bufsize = buffersize;
				buffer = new char[buffersize];
				bufline = new int[buffersize];
				bufcolumn = new int[buffersize];
			}
			prevCharIsLF = prevCharIsCR = false;
			tokenBegin = inBuf = maxNextCharInd = 0;
			bufpos = - 1;
		}
		
		public virtual void  ReInit(System.IO.StreamReader dstream, int startline, int startcolumn)
		{
			ReInit(dstream, startline, startcolumn, 4096);
		}
		
		public virtual void  ReInit(System.IO.StreamReader dstream)
		{
			ReInit(dstream, 1, 1, 4096);
		}
		public SimpleCharStream(System.IO.Stream dstream, int startline, int startcolumn, int buffersize) : this(new System.IO.StreamReader(dstream, System.Text.Encoding.Default), startline, startcolumn, 4096)
		{
		}
		
		public SimpleCharStream(System.IO.Stream dstream, int startline, int startcolumn) : this(dstream, startline, startcolumn, 4096)
		{
		}
		
		public SimpleCharStream(System.IO.Stream dstream) : this(dstream, 1, 1, 4096)
		{
		}
		
		public virtual void  ReInit(System.IO.Stream dstream, int startline, int startcolumn, int buffersize)
		{
			ReInit(new System.IO.StreamReader(dstream, System.Text.Encoding.Default), startline, startcolumn, 4096);
		}
		
		public virtual void  ReInit(System.IO.Stream dstream)
		{
			ReInit(dstream, 1, 1, 4096);
		}
		public virtual void  ReInit(System.IO.Stream dstream, int startline, int startcolumn)
		{
			ReInit(dstream, startline, startcolumn, 4096);
		}
		public virtual System.String GetImage()
		{
			if (bufpos >= tokenBegin)
				return new System.String(buffer, tokenBegin, bufpos - tokenBegin + 1);
			else
				return new System.String(buffer, tokenBegin, bufsize - tokenBegin) + new System.String(buffer, 0, bufpos + 1);
		}
		
		public virtual char[] GetSuffix(int len)
		{
			char[] ret = new char[len];
			
			if ((bufpos + 1) >= len)
				Array.Copy(buffer, bufpos - len + 1, ret, 0, len);
			else
			{
				Array.Copy(buffer, bufsize - (len - bufpos - 1), ret, 0, len - bufpos - 1);
				Array.Copy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
			}
			
			return ret;
		}
		
		public virtual void  Done()
		{
			buffer = null;
			bufline = null;
			bufcolumn = null;
		}
		
		/// <summary> Method to adjust line and column numbers for the start of a token.</summary>
		public virtual void  AdjustBeginLineColumn(int newLine, int newCol)
		{
			int start = tokenBegin;
			int len;
			
			if (bufpos >= tokenBegin)
			{
				len = bufpos - tokenBegin + inBuf + 1;
			}
			else
			{
				len = bufsize - tokenBegin + bufpos + 1 + inBuf;
			}
			
			int i = 0, j = 0, k = 0;
			int nextColDiff = 0, columnDiff = 0;
			
			while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
			{
				bufline[j] = newLine;
				nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
				bufcolumn[j] = newCol + columnDiff;
				columnDiff = nextColDiff;
				i++;
			}
			
			if (i < len)
			{
				bufline[j] = newLine++;
				bufcolumn[j] = newCol + columnDiff;
				
				while (i++ < len)
				{
					if (bufline[j = start % bufsize] != bufline[++start % bufsize])
						bufline[j] = newLine++;
					else
						bufline[j] = newLine;
				}
			}
			
			line = bufline[j];
			column = bufcolumn[j];
		}
	}
}